import { inject, provide, reactive, ref, h } from 'vue'
import { sendServiceData } from '../service'
import {
    copyObjectDeep,
    copyObjectSameTo, deepCopyObject, hasOwnProperty,
    popAskWin2,
    popMessage
} from '../utils/normalUtils'
import { getServiceErrorMsg } from '../service/base/request'
import { ElMessageBox } from 'element-plus'
import DeletePop from '../../components/normal/DeletePop.vue'
import { usePageQuery } from './PageQuery'


export const formWinEmits = ['success']

export const formWinProps = {
    // 是否编辑状态
    isEdit: {
      type: Boolean,
      default: false
    },
    // 编辑对象
    editData: {
        type: Object,
        default: function() {
            return null
        }
    }
}

/**
 * 询问接口调用
 * @param deleteMethod
 * @param sendData
 * @param stateProxy
 * @param msg
 */
export async function askWinExecute(deleteMethod:any, sendData: any, stateProxy:any = null, msg = '是否确认删除?') {
    await popAskWin2(msg)
    const result = await sendServiceData(deleteMethod, sendData, stateProxy)
    return result
}

/**
 * 强制删除提示窗口
 * @param message
 * @param checkLabel
 */
export function popForceDeleteWin(message = '是否确认删除对象?', checkLabel = '强制删除') {
    const checked = ref<boolean | string | number>(false)
    return new Promise((resolve, reject) => {
        ElMessageBox({
            title: '',
            showCancelButton: true,
            cancelButtonText: '取消',
            confirmButtonText: '确定',
            message: () =>
                h(DeletePop, {
                    message,
                    checkLabel,
                    modelValue: checked.value,
                    'onUpdate:modelValue': (val: boolean | string | number) => {
                        checked.value = val
                    }
                })
        }).then(() => {
            resolve(checked.value)
        }).catch(() => {
            // eslint-disable-next-line prefer-promise-reject-errors
            reject()
        })
    })
}

/**
 * 控制状态对象
 */
export class PopState {
    isLoading = false
    // 是否弹出编辑窗口
    isPopEdit = false
    // 是否弹出创建窗口
    isPopCreate = false
    // 是否弹出详情窗口
    isPopDetail = false
    // 弹出窗口总状态
    isPop = false
    params:any = null
    // 可绑定的编辑对象
    editData:any = null
    // 查询条件
    search:any = reactive({})
    // 默认列表
    dataListSource:any[] = []
    // 多选对象
    checkDataSource:any[] = []

    detailMethod = null
    updateMethod = null
    createMethod = null
}

/**
 * 表单验证
 * @param formViewRef
 */
export async function validFormRef(formViewRef:any) {
    const validResult = await formViewRef.value.validate()
    return validResult
}

/**
 * 表单验证 - 某项
 * @param formViewRef
 * @param field
 */
export async function validateRefField(formViewRef:any, field:string) {
    let validResult = false
    await formViewRef.value.validateField(field, (valid:any) => {
        validResult = valid
    })
    return validResult
}

/**
 * 表单验证
 * @param formViewRef
 * @param fields
 */
export async function validateRefFields(formViewRef:any, fields:string[]) {
     for (const item of fields) {
         const result = validateRefField(formViewRef, item)
         if (!result) return false
     }
     return true
}

const joinObjectValue = (objA:any, objB:any) => {
    for (const att in objB) {
        if (!Object.prototype.hasOwnProperty.call(objA, att)) { objA[att] = objB[att] }
    }
}

/**
 * 表单处理
 */
export function useFormData(viewState:any = null, options:any = null, provideName:any = '') {
    // 表单对象
    const formRef = ref()
    // 根控制模型
    let winPm:any = null
    if (provideName) {
        if (typeof provideName === 'string')winPm = inject(provideName)
        else winPm = provideName
    }
    // 初始化状态
    if (viewState) {
        if (!hasOwnProperty(viewState, 'isLoading'))viewState.isLoading = false
        if (!hasOwnProperty(viewState, 'formData'))viewState.formData = {}
    }
    // 窗口状态
    let popState:PopState = reactive(new PopState())
    let instance = {
        createMethod: null,
        updateMethod: null,
        detailMethod: null,
        params: null
    }
    if (options) copyObjectSameTo(options, popState)
    if (winPm) {
        popState = winPm.popState
        instance = winPm.instance
    }
    if (options)Object.assign(instance, options)

    const actions = {
        /**
         * 验证表单
         */
         async validForm() {
            const result = await validFormRef(formRef)
            return result
        },

        /**
         * 表单验证后处理
         * @param callback
         */
        async validFormHandler(callback:any) {
            const result = await actions.validForm()
            if (result)callback()
        },


        /**
         * 表单提交处理
         * @param formData
         * @param copy 是否深拷贝  默认浅拷贝
         */
        async submitHandler(formData:any = null, copy = false, isId = false) {
            // 验证表单
            const validFlag = await actions.validForm()
            if (!validFlag) return
            // 参数
            const send = !isId ? actions.getSubmitData(formData) : actions.getSubmitDataId(formData)
            // 提交数据
            const result:any = await sendServiceData(popState.isPopEdit ? instance.updateMethod : instance.createMethod, send, viewState)
            // 处理成功
            actions.submitSuccess(result)
            return result
        },

        /**
         * 单独抽个函数
         * @param formData
         * @param copy
         */
        getSubmitData(formData:any = null, copy = false) {
            if (!formData)formData = viewState.formData || {}
            let send:any = { id: '' }
            if (copy)send = deepCopyObject(formData)
            else Object.assign(send, formData)
            if (!popState.isPopEdit && Object.prototype.hasOwnProperty.call(send, 'id')) {
                delete send.id
            }
            return send
        },

        /**
         * 单独抽个函数有id
         * @param formData
         * @param copy
         */
        getSubmitDataId(formData:any = null, copy = false) {
            if (!formData)formData = viewState.formData || {}
            let send:any = { }
            if (copy)send = copyObjectDeep(formData, 1)
            else Object.assign(send, formData)
            return send
        },


        // 成功处理
        submitSuccess(result:any) {
            if (winPm) winPm.actions.success(result)
        },

        /**
         * 初始化
         * @param query
         * @param params
         */
        async initFormData(query = false, params:any = null) {
            if (!popState.isPopEdit) return
            if (query) await actions.queryDetail(popState.editData, params)
            else copyObjectSameTo(popState.editData || {}, viewState.formData)
        },

        /**
         * 查询详情
         * @param data
         * @param params
         * @param init
         */
        async queryDetail(data:any, params:any = null, init = true) {
            const send = params || { id: data.id }
            const result:any = await sendServiceData(instance.detailMethod, send, viewState)
            if (result && init)copyObjectSameTo(viewState.formData, result)
            return result
        },
        close() {
            if (winPm)winPm.actions.close()
        }
    }

    return {
        formRef,
        actions,
        root: winPm,
        viewState,
        rootActions: winPm ? winPm.actions : null,
        rootPopState: popState,
        popState,
        instance
    }
}

/**
 *
 * @param viewState
 * @param options
 * @param provideName
 */
export function usePopWinInject(viewState:any = null, options:any = null, provideName = 'popWinPm') {
    return useFormData(viewState, options, provideName)
}

/**
 *
 * @param options
 * @param provideName
 */
export function usePopWinProvide(options:any = null, provideName = 'popWinPm') {
    return usePopWinState(options, provideName)
}

/**
 * 表单窗口
 * @param options
 * @param provideName
 */
export function usePopWinState(options:any = null, provideName = '') {
    const state = reactive(new PopState())
    // 实例对象
    const instance:any = {
        queryMethod: null,
        deleteMethod: null,
        updateMethod: null,
        detailMethod: null,
        params: null,
        forceDelete: false, // 统一强制删除逻辑
        forceField: 'isForce',
        page: false,
        deletePatch: true // 相同批量模式删除接口
    }
    // 先留着
    let pagePM: any = null
    let pageInstance:any = null
    // 初始化
    if (options)Object.assign(instance, options)
    // 分页查询
    if (instance.page) {
        // 列表
        pageInstance = usePageQuery({
            queryMethod: instance.queryMethod
        })
        pagePM = pageInstance.actions
    }
    // 操作
    const actions = {
        /**
         *  创建 popState.editData
         */
        popCreate(params:any = null) {
            state.editData = params
            Object.assign(state, {
                isPopEdit: false,
                isPopCreate: true,
                isPopDetail: false,
                isPop: true
            })
            actions.popHandler(params, 'create')
        },

        /**
         * 编辑
         * @param item
         */
        popEdit(item: any) {
            state.editData = item
            Object.assign(state, {
                isPopEdit: true,
                isPopCreate: false,
                isPopDetail: false,
                isPop: true
            })
            actions.popHandler(item, 'edit')
        },

        /**
         * 详情
         * @param item
         */
        popDetail(item: any) {
            state.editData = item
            Object.assign(state, {
                isPopEdit: false,
                isPopCreate: false,
                isPopDetail: true,
                isPop: false
            })
            actions.popHandler(item, 'detail')
        },

        /**
         * 弹出处理
         * @param item
         * @param type
         */
        popHandler(item: any, type = '') {

        },

        /**
         * 关闭窗体
         */
        close() {
            Object.assign(state, {
                isPopEdit: false,
                isPopCreate: false,
                isPopDetail: false,
                isPop: false,
                editData: null
            })
        },

        /**
         * 操作成功后处理
         * @param data
         * @param req
         * @param message
         */
        success(data:any = null, req = true, message = '操作成功') {
            // 提示信息
            if (message) popMessage(message)
            // 关闭窗口
            actions.close()
            // 重新查询
            if (req)actions.reQuery()
            // 扩展回调
            actions.successHandler(data)
        },

        // 扩展
        successHandler(data:any) {

        },

        // --------------------------------------------------------------------------- list -----------------------------------------

        /**
         * 查询列表
         * @param params
         */
        async queryList(params: any = null) {
            const send = deepCopyObject(params || state.search)
            if (pagePM) await pagePM.queryList(send)
            else if (instance.queryMethod) {
                const result = await sendServiceData(instance.queryMethod, send, state)
                state.dataListSource = result || []
            }
        },

        /**
         * 重新查询
         * @param params
         */
        async reQuery(params: any = null) {
            await actions.queryList()
        },

        /**
         * 选中数据变化
         * @param items
         */
        checkDataHandler(items:any[]) {
            state.checkDataSource = items
        },

        /**
         * 删除某个对象
         * @param item
         * @param isMore
         * @param ask
         * @param moreSend
         */
        async deleteItem(item: any, isMore = false, ask = true, moreSend = false) {
            if (instance.deletePatch) {
                item = [item]
                moreSend = true
            }
            const params: any = actions.getDeleteParams(item, isMore, moreSend)
            let result = null
            if (instance.forceDelete) {
                const isForce = await popForceDeleteWin()
                if (isForce)result = await actions.forceDeleteItem(params)
                else result = await sendServiceData(instance.deleteMethod, params, state)
            } else {
                await popAskWin2('是否确认删除?')
                result = await sendServiceData(instance.deleteMethod, params, state)
            }
            actions.deleteResultHandler(result)

            // if (ask)  await popAskWin2('是否确认删除?')
            // actions.executeDelete(params,(result:any)=>{
            //     actions.deleteResultHandler(result, item);
            // });
        },

        /**
         * 执行删除 如果指定强制删除 删除失败强制删除
         * @param params
         * @param resultHandler
         */
         executeDelete(params:any, resultHandler:any) {
            state.isLoading = true;
            (instance.deleteMethod as any)(params)
                .then((result: any) => {
                    state.isLoading = false
                    resultHandler(result)
                })
                .catch(async (res: any) => {
                    state.isLoading = false
                    await actions.deleteErrorHandler(res, params, resultHandler)
                })
        },

        /**
         * 删除错误处理
         * @param error
         * @param params
         * @param resultHandler
         */
        async deleteErrorHandler(error:any, params:any, resultHandler:any) {
            if (!instance.forceDelete || !actions.isForceState(error)) {
                popMessage(getServiceErrorMsg(error))
                return
            }
            await popAskWin2(getServiceErrorMsg(error))
            const result = await actions.forceDeleteItem(params)
            resultHandler(result)
        },

        /**
         * 是否是强制执行的错误
         * @param res
         */
        isForceState(res:any) {
          return res.data && res.data.code === 'BIZ_ERROR'
        },

        /**
         * 强制删除执行
         * @param params
         */
        async forceDeleteItem(params:any) {
            const send = { ...params }
            send[instance.forceField] = true
            const result = await sendServiceData(instance.deleteMethod, send, state)
            return result
        },


        /**
         * 删除多个
         */
        async deleteItems(items: any[]|null = null): Promise<void> {
            if (!items)items = state.checkDataSource || []
            if (items.length === 0) return
            await actions.deleteItem(state.checkDataSource, true)
        },

        /**
         * 获得删除参数 默认多个逗号分隔
         * @param data
         * @param isMore
         * @param moreSend
         */
        getDeleteParams(data: any, isMore = false, moreSend = false): any {
            if (isMore || moreSend) return data.map((item: any) => item.id)
            return { id: data.id }
        },

        /**
         * 删除返回处理
         * @param result
         * @param oldData
         */
        deleteResultHandler(result: any, oldData: any = null) {
            popMessage('操作成功！', 'success')
            actions.reQuery()
        }
    }

    // 控制对象
    const control = {
        popState: state,
        actions,
        instance,
        pageInstance,
        pageData: pageInstance ? pageInstance.pageData : null,
        pageActions: pageInstance ? pageInstance.actions : null
    }
    // 注入控制对象
    if (provideName)provide(provideName, control)
    return control
}
